﻿#pragma once

#include "PublicService/ErrLog.h"
#include "PublicService/ObjectFactory.h"
#include "BusinessLayer/DataPool.h"
#include <chrono>

namespace BusinessLayer
{
class ContainerForDevice;
}

namespace DeviceLayer {


class Device : public Object
{
//---------------------------------------------------------------------
    //以下这个部分，仅用于ContainerForDevice实现定时调用本类对象的QueryData,
    //一是保存配置数据，二是保存中间时间点。
    friend class BusinessLayer::ContainerForDevice;
private:
    class tagAutoQuerySetup
    {
    public:
        bool independentQueryTask { false };
        int  autoQueryTimeSpan { 0 };   //0 = do not auto-query data.
        std::chrono::steady_clock::time_point lastCallTime; //last time tick value when QueryData was called.
    } autoQuerySetup;
//----------------------------------------------------------------------


protected:

    std::shared_ptr<BusinessLayer::DataPool> dataPool { nullptr };
    //这个函数会被ContainerForDevice在创建设备对象时调用。
    inline void SetDataPoolObj(std::shared_ptr<BusinessLayer::DataPool>& dataPool)
    {
        this->dataPool = dataPool;
    }

    /**
     * @brief 如果设备需要将数据保存到数据池以便上层模块使用，应调用本函数。设备不应直接操作DataPool类来保存数据。
     * @param fieldName 数据字段名。数据将以 “设备对象名.数据字段名” 为名称保存到数据池中。
     * @param value 数据值
     */
    inline void PutDataToPool(const QString& fieldName, const QVariant& value)
    {
        if (dataPool != nullptr)
            dataPool->put(name, fieldName, value);
    }
public:
    Device() {}
    virtual ~Device() {}

    /**
     * @brief 如果需要本框架自动定时让设备类从具体的硬件设备收发，应重载此函数，并在SettingData.xml的本设备的autoQueryTimeSpan属性设置定时参数。
     *   注意：如果设置了自动数据采集，也就是SettingData.xml对应的Devices/Device的autoQueryTimeSpan不为0，
     *   则：由于QueryData会被另一个线程调用，如果程序中需要操作设备，对设备发送命令，就必须在QueryData的实现中加入同步机制。
     *   例外：如果设备通过CANHub操作CAN总线，则无需考虑同步；CANHub已经进行了同步。
     *   在这里可以使用（也只能使用）PutDataToPool将取到的数据放到业务层的DataPool数据池中，以便其他模块，包括呈现层模块使用。
     * @return 成功返回true，失败返回false。
     */
    virtual bool QueryData()
    {
        return true;
    }
};

}
